package com.hxd.common.core.spring;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.UrlPathHelper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hxd.common.Result;
import com.hxd.common.constant.Constants;
import com.hxd.common.constant.UserConstants;
import com.hxd.common.enums.UserStatus;
import com.hxd.common.utils.StringUtils;
import com.hxd.entity.SysConfig;
import com.hxd.entity.SysMenu;
import com.hxd.entity.SysUser;
import com.hxd.pojo.TokenVO;
import com.hxd.service.SysConfigService;
import com.hxd.service.SysMenuService;
import com.hxd.service.SysUserService;
import com.hxd.service.TokenService;

import cn.hutool.json.JSONUtil;

@Component
public class AuthenticationInterceptor extends HandlerInterceptorAdapter {
	
	@Autowired
	private TokenService tokenService;
	
	@Autowired
	private SysConfigService sysConfigService;
	
	@Autowired
	private SysUserService sysUserService;
	
	@Autowired
	private SysMenuService sysMenuService;
	
	private static final UrlPathHelper pathHelper = new UrlPathHelper();
	
	private static final AntPathMatcher antPathMatcher = new AntPathMatcher();

	String[] excludeUrls = {"/login", "/sys-user/register"};
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// 获取权限开关配置
		SysConfig sysConfig = sysConfigService.getOne(new QueryWrapper<SysConfig>().eq(SysConfig.Fields.ckey, Constants.AUTH_SWITCH));
		if(sysConfig != null && Constants.CLOSE.equals(sysConfig.getCvalue())) {
			return true;
		}
		
		// 获取请求URL
		String path = pathHelper.getServletPath(request);
		// 排除URL
		for (String url : excludeUrls) {
			if (antPathMatcher.match(url, path)) {
				return true;
			}
		}
		
		// token验证
		String token = request.getHeader(Constants.TOKEN);
		if(StringUtils.isEmpty(token)) {
			renderToUnauthorized(request, response, "token expired");
			return false;
		}
		TokenVO tokenVO = tokenService.getToken(token);
		if(tokenVO == null || tokenVO.getExpireTime() < System.currentTimeMillis()) {
			renderToUnauthorized(request, response, "token expired");
			return false;
		}
		
		// 用户验证
		SysUser user = sysUserService.getById(tokenVO.getId());
		if(user == null || UserStatus.DISABLE.getCode().equals(user.getStatus())) {
			renderToUnauthorized(request, response, "user locked");
			return false;
		}
		request.setAttribute(UserConstants.LOGIN_USER, user);
		
		// 权限验证
		List<SysMenu> sysMenuList = sysMenuService.getUserMenu(user.getId());
		for (SysMenu sysMenu : sysMenuList) {
			if(sysMenu != null && path.equals(sysMenu.getUrl())) {
				return true;
			}
		}
		renderToUnauthorized(request, response, "no access");
		return false;
	}
	
	private void renderToUnauthorized(HttpServletRequest request, HttpServletResponse response, String msg) {
		String resStr = JSONUtil.toJsonStr(new Result(HttpStatus.UNAUTHORIZED.value(), msg));
		
		response.setContentType("application/json;charset=utf-8");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
		
		try {
			response.getWriter().print(resStr);
			response.flushBuffer();
		} catch (IOException e) {

		}
	}
	
}
